<template>
  <split-pane :min-percent='10' :default-percent='18' split="vertical" style="position: inherit;">
    <template slot="paneL">
      <Tree class="zc-scroll" style="height: 100vh;" ref="tree" @on-change="target = $event" @on-data-change="treeData = $event"/>
    </template>
    <div slot="paneR" class="zc-scroll" :style="{height: $docHeight(-5) + 'px'}">
      <split-pane v-on:resize="defaultPercent = $event" split="horizontal" :default-percent='defaultPercent'>
        <template slot="paneL">
          <MonacoEditor
              :language="language"
              class="vs"
              theme="vs"
              v-model="code"
              :options="options"
              :height="editorHeight"
              :editorMounted="onMounted"
          >
          </MonacoEditor>
          <vxe-toolbar perfect>
            <template #buttons>
              <div style="margin-right: 20px; margin-left: 20px;">
                <vxe-button circle icon="vxe-icon--caret-right" title="Run" @click="preview()"></vxe-button>
                <vxe-button circle icon="far fa-save" :status="change ? 'primary' : 'default'" title="Save" @click="save()"></vxe-button>
                <vxe-button circle icon="fas fa-eye" title="Preview" @click="viewPage()"></vxe-button>
                <span style="margin-left: 20px;">{{ path2Id[id] }}</span>
              </div>
            </template>
          </vxe-toolbar>
        </template>
        <div slot="paneR" style="height: 100%; padding: 5px;">
          <iframe border="0" height="100%" width="100%" :src="viewSrc" @load="frameOnload"></iframe>
        </div>
      </split-pane>
    </div>
  </split-pane>
</template>

<script>

import splitPane from 'vue-splitpane'
import MonacoEditor from './monaco'
import Code from '@/libs/code-utils'

export default {
  name: "WebEditor",
  components: {
    Tree: window.$import(14),
    MonacoEditor,
    splitPane
  },
  data() {
    return {
      code: null,
      target: null,
      treeData: [],
      editor: null,
      viewWin: null,
      defaultPercent: 60,
      viewSrc: '/' + this.$route.params.type + '/preview',
      options: {
        selectOnLineNumbers: true,
        roundedSelection: false,
        readOnly: false,
        automaticLayout: true,
        showUnused: true,
        showFoldingControls: "always",
        formatOnPaste: true,
        formatOnType: true,
        folding: true,
        minimap: {
          enabled: true
        },
        cursorStyle: 'line', // 光标样式
        glyphMargin: true, // 字形边缘
        useTabStops: false,
        fontSize: 16, // 字体大小
        autoIndent: true   //自动布局
      },
      change: false,
      key: 'trees'
    }
  },
  computed: {
    isViewReady() {
      return this.code != null && this.viewWin != null
    },
    editorHeight() {
      return Math.round((this.defaultPercent / 100 * this.$docHeight()) - 50)
    },
    path2Id() {
      let [path, map] = [this.path(this.treeData, null, {}, this.key), {}]
      for (let key in path) {
        let trees = path[key][this.key].reverse()
        let treeId = trees.reduce((cols, e) => { cols.push(path[e].name); return cols }, []).join('/')
        map[treeId] = key
        map[key] = treeId
      }
      return map
    },
    type() {
      return this.target ? (this.target.type || 'dir') : 'dir'
    },
    language() {
      return this.type !== 'css' ? 'html' : this.type
    },
    id() {
      return this.target ? this.target.id : this.$route.query.id
    }
  },
  watch: {
    id: {
      immediate: true,
      handler: 'info'
    },
    code() {
      this.change = true
    },
    isViewReady: 'preview'
  },
  methods: {
    onMounted(editor) {
      this.editor = editor
    },
    frameOnload({target}) {
      this.viewWin = target.contentWindow.$view
    },
    /**
     * 获取组件模板
     */
    info(id = this.id) {
      id && this.$ajax('/sys/ele/template?id=' + id)
          .then(res => this.code = res.data || Code.baseCode)
          .then(this.preview)
          .then(() => this.change = false)
    },
    /**
     * 预览
     */
    preview() {
      this.isViewReady && this.viewWin.show(Code.getEleVue(this, this.code, this.path2Id), this.id)
    },
    /**
     * viewPage
     */
    viewPage () {
      window.open('/' + this.$route.params.type + '/preview?id=' + this.id)
    },
    /**
     * 保存
     */
    save() {
      if (!this.code) {
        return alert('模板代码不能为空!')
      }
      let data = {...this.getEleVue(), id: this.id, type: this.type}
      this.$post('/sys/ele/save/file', data).then(res => {
        this.target = res.data
      }).then(() => {
        this.$XModal.message({content: '操作成功!', status: 'success'})
      }).then(() => this.change = false)
    },
    getEleVue(template = this.code) {
      let encryptEle = Code.getEncryptedEleVue(this, template, this.path2Id)
      return {
        template,
        encryptEle
      }
    },
    path(arr, pid = '-123', path2Id, key = this.key) {
      for (let i = 0; i < arr.length; i ++) {
        let e = arr[i]
        this.$set(e, key, [e.id].concat(path2Id[pid] ? path2Id[pid][key] : []))
        path2Id[e.id] = e
        if (e.children) {
          this.path(e.children, e.id, path2Id)
        }
      }
      return path2Id
    }
  }
}
</script>
<style>
/* @import '../style/scrollbar.css'; */
</style>
